<?php
/**
 * Controlador para listar/ver registros de uma tabela.
 * @author Renato Lenz CostaLima @ TICE/PC4
 * @version 1.0
 */
class TICE_Controlador_Lista extends Zend_Controller_Action {

	public
		$tabela,
		$modelo,
		$pk = 'id',
		$debug = false,
		$debugEcho = false,
		$debugDie = false;
		
	protected $nomeSecao;	
	
	function __construct(Zend_Controller_Request_Abstract $request, Zend_Controller_Response_Abstract $response, array $invokeArgs = array() ) {
		parent::__construct($request, $response, $invokeArgs);
		$this->initModelo();

		// após inicialização do modelo, liga o Profiler
		$this->debugEcho |= $this->debugDie;
		$this->debug |= $this->debugEcho;
		if ($this->debug) {
			$this->modelo->getAdapter()->getProfiler()->setEnabled(true);
			$this->view->debug = array();
		}

	}
	/**
	 * Inicializa modelo
	 */
	protected function initModelo() {
		if ($this->modelo == null) {
			$this->modelo = new PC4_Db_Table($this->tabela);
		}
	}
	
	/**
	 * Antes de dispachar, envia informações importantes de acordo com configurações
	 * @param $this->tabela
	 * @param $this->nomeSecao
	 * @param $this->campos
	 * @param $this->infos
	 * @return
	 * 	$this->view->infoTabela
	 * 	$this->view->url
	 * 	$this->view->nomeSecao
	 * 	$this->view->campos
	 */
	function preDispatch() {
		$this->view->addPastaView('lista', array_search('', $this->view->getPastasView()));
		$info = $this->modelo->info();
		$this->tabela = $info['name'];
		$this->view->infoTabela = $info;

		$request = $this->getRequest();
		
		$this->view->url = $this->view->serverUrl($this->_helper->url(''));
		$this->view->nomeSecao = (empty($this->nomeSecao)) ? ucfirst($request->getControllerName()) : $this->nomeSecao;
		
		// passa as informações dos campos para a view
		$this->campos = (empty($this->campos)) ? $this->view->infoTabela['cols'] : $this->campos;
		$campos = array();
		foreach ($this->campos as $campo => $cabecalho) {
			if (is_numeric($campo)) {
				$campo = $cabecalho;
				$info = array('cabecalho' => ucfirst($cabecalho));		
			}
			else if (is_string($cabecalho)) {
				$info = array('cabecalho' => $cabecalho);
			}
			else {
				$info = $cabecalho;
				if (empty($info['cabecalho'])) {
					$info['cabecalho'] = ucfirst($campo);
				}
			}
			$campos[$campo] = $info;
			$campos[$campo]['campo'] = $campo;
			$campos[$campo]['url'] = $this->view->url;
			$campos[$campo]['nomeSecao'] = $this->view->nomeSecao;
		}
		if (is_array($this->infos)) {
			$campos = array_merge_recursive($campos, $this->infos);
		}
		$this->view->campos = $campos;
	}

	/**
	 * Procura por um viewScript em uma hierarquia de pastas.
	 * @see Zend_Controller_Action::postDispatch()
	 */
	function postDispatch() {
		if ($this->debug) {
			$qs = $this->modelo->getAdapter()->getProfiler()->getQueryProfiles(null, true);
			$i = 0;
			if (is_array($qs)) { 
				foreach ($qs as $q) {
					$this->view->debug['consultas'][] = '<br />' . $q->getQuery() . ' (' . implode(', ', $q->getQueryParams()) . ') [' . $q->getElapsedSecs() . 's]'; 
				}
			}
			$this->modelo->getAdapter()->getProfiler()->setEnabled(false);
		}
    	// desabilta o layout quando a requisição for assíncrona
		if ($this->getRequest()->isXmlHttpRequest()) {
			$this->_helper->layout()->disableLayout();
		}

		// escolhe uma view pelo $_REQUEST
		$view = $this->_getParam('view');
		if (!empty($view)) {
			$this->_helper->layout()->disableLayout();
    		$this->_helper->viewRenderer($view, null, true);
		}
	
		if ($this->debugEcho) {
			new d($this->view->debug);
		}
		if ($this->debugDie) {
			die;
		}
	}

	/**
	 * Adiciona uma pasta na hierarquia de pastas onde será procurada a view
	 * @param string $pasta
	 * @param int $i A posição onde a pasta será adicionada
	 * @deprecated Use $this->view->addPastaView()
	 */
	protected function addPastaView($pasta, $i = 0) {
		$this->view->addPastaView($pasta, $i);
	}	
	protected function prependPastaView($pasta) {
		$this->view->prependPastaView($pasta);
	}
	protected function appendPastaView($pasta) {
		$this->view->appendPastaView($pasta);
	}
	
	/**
	 * O padrão é chamar a lista
	 */
    public function indexAction()
    {
    	$this->lista();
    }
    
	/**
	 * Popula a view com a lista de todos os registros
	 * @param int $_GET['p'] pagina
	 * @param int $_GET['l'] limite
	 * @return
	 * 	Zend_Db_Table_Rowset_Abstract $this->view->rs,
	 *  int $this->view->total,
	 *  int $this->view->pagina,
	 *  int $this->view->limite
	 *  int $this->view->totalPaginas
	 *  string $this->view->url
	 */
	public function listaAction() {
		return $this->lista();
	}
	/**
	 * Popula a view com a lista de todos os registros
	 * @param int $_GET['p'] pagina
	 * @param int $_GET['l'] limite
	 * @return
	 * 	Zend_Db_Table_Rowset_Abstract $this->view->rs,
	 *  int $this->view->total,
	 *  int $this->view->pagina,
	 *  int $this->view->limite
	 *  int $this->view->totalPaginas
	 *  string $this->view->url
	 */
	protected function lista($where = null, $order = null, $count = null, $offset = null) {
		$resultado = $this->getLista($where, $order, $count, $offset);
		$this->resultadoLista($resultado);
		return $resultado;
	}
	/**
	 * Devolve um array com informações sobre a lista de todos registro
	 * @param int $_GET['p'] pagina
	 * @param int $_GET['l'] limite
	 * @return array(
	 * 	rs => Zend_Db_Table_Rowset_Abstract,
	 *  total => int,
	 *  pagina => int,
	 *  limite => int,
	 *  totalPaginas => int,
	 *  url => string
	 * )
	 */
	protected function getLista($where = null, $order = null, $count = null, $offset = null) {
		try {
			$pagina = $this->_getParam('p');
			if (empty($pagina)) {
				$pagina = 1;
			} 
			$limite = $this->_getParam('l');
			if (empty($limite)) {
				$limite = 25;
			}
			
			$limite = is_null($count) ? $limite : $count; 
			$order = is_null($order) ? $this->modelo->getAlias($this->tabela) . '.' . $this->pk . ' DESC': $order; 
			$offset = ($pagina - 1) * $limite;
			
			
			// TODO implementar busca e ordem
			$rs = $this->getDados($where, $order, $limite, $offset);	
			// TODO REFATORAR - será que sempre tem paginação?
			// TODO Melhorar a questão da paginação. Talvez utilizar o Zend_Paginator
			// adiciona informações sobre paginação. talvez devesse ser opcional (falta de coesão)
            $total = $this->modelo->getLastCount();
			
			// adiciona as informações na view
			$resultado = array(
				'rs' => $rs,
				'pagina' => $pagina,
				'limite' => $limite,
				'total' => $total
			);
			if ($limite == 0) {
				$resultado['totalPaginas'] = 1;
			}
			else {
				$resultado['totalPaginas'] = ceil($total / $limite);
			}
			$sucesso = true;
		}
		catch (Exception $e) {
			$resultado['msg'] = 'Erro: ' . $e->getMessage();
			$sucesso = false;
		}
		$resultado['resultado'] = $sucesso;
		return $resultado;
	}
    /**
     * Recupera os dados a serem listados
     * @param string|array|Zend_Db_Table_Select $where  OPTIONAL An SQL WHERE clause or Zend_Db_Table_Select object.
     * @param string|array                      $order  OPTIONAL An SQL ORDER clause.
     * @param int                               $count  OPTIONAL An SQL LIMIT count.
     * @param int                               $offset OPTIONAL An SQL LIMIT offset.
     * @param Zend_Db_Table_Rowset
     */
    protected function getDados($where = null, $order = null, $count = null, $offset = null) {
        return $this->modelo->getLista($where, $order, $count, $offset);
    }
	/**
	 * Popula a view com o array de resultado
	 * @param array $resultado
	 */
	protected function resultadoLista($resultado) {
		$this->resultado($resultado);
	}
	
	/**
	 * Mostra em detalhes um registro
	 * @param int $_GET['id']
	 * @return Zend_Db_Table_Row $this->view->r
	 */
	public function veAction() {
		$resultado = array();
		$pk = $this->pk;
		$id = $this->_getParam($pk);
		try {
			$r = $this->getDado($id);
			$resultado['r'] = $r;
			$resultado[$this->pk] = $r->$pk;
			$sucesso = (!empty($r));
		}
		catch (Exception $e) {
			$resultado['erro'] = 'Não achou o registro';
			$sucesso = false;
		}
		$resultado['resultado'] = $sucesso;
		$this->resultadoVe($resultado);
	}
	/**
	 * Recupera um registro pelo id
	 * @param int $id
	 * @return Zend_Db_Table_Row|false
	 */
	protected function getDado($id) {
		$where = $this->modelo->getAdapter()->quoteInto($this->modelo->getAlias($this->tabela) . '.' . $this->pk . ' = ?', $id);
		$rs = $this->modelo->getLista($where);
		return (!empty($rs)) ? $rs[0] : null;
	}
	/**
	 * Popula a view com o array de resultado
	 * @param array $resultado
	 */
	protected function resultadoVe($resultado) {
		$this->resultado($resultado);
	}
	
	/**
	 * Popula a view com o array de resultado
	 * @param array $resultado
	 */
	protected function resultado($resultado) {
		if ($this->debug) {
			$this->view->debug['resultado'] = $resultado;
		}
		// manda para a view
		
		$this->view->assign($resultado);
	}
}